package com.opal.system.service.impl;

import com.opal.consts.WSC;
import com.opal.domain.ReturnMessageData;
import com.opal.model.DataGridData;
import com.opal.system.entity.table.*;
import com.opal.system.mapper.mysql.*;
import com.opal.system.service.OpalUserService;
import com.opal.consts.CommonConst;
import com.opal.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class OpalUserServiceImpl implements OpalUserService {

	@Autowired
	private OpalUserMapper opalUserMapper;
	@Autowired
	private OpalUserRoleMapper opalUserRole;
	@Autowired
	private OpalUserRoleMapper opalUserRoleMapper;
	@Autowired
	private OpalRoleMapper opalRoleMapper;
	@Autowired
	private OpalHrorgMapper opalHrorgMapper;
	@Autowired
	private OpalUserExtendMapper opalUserExtendMapper;
	@Autowired
	private OpalDeptMapper opalDeptMapper;


	@Override
	public OpalUser findById(String userName) {
		OpalUserExample ue = new OpalUserExample();
		ue.createCriteria().andUserCodeEqualTo(userName);
		List<OpalUser> list = opalUserMapper.selectByExample(ue);
		if(list !=null && list.size() > 0 ) {
			OpalUser user = list.get(0);
			if (user != null) {
				return user;
			} 
		}
			return null;
	}

	@Override
	public List<OpalUser> selectAllUserService() {
		OpalUserExample example= new OpalUserExample();
		List<OpalUser> opalUsers = opalUserMapper.selectByExample(example);
		return opalUsers;
	}

	@Override
	public Object selectAllUserTreeService(String userName) {
		OpalUserExample example= new OpalUserExample();
		userName ="%"+userName+"%";
	example.createCriteria().andUserNameLike(userName);
		List<OpalUser> opalUsers = opalUserMapper.selectByExample(example);
		//tree需要属性名为id和text
		List<Map<String, Object>> collect = opalUsers.stream().map((OpalUser opalUser) -> {
			Map<String, Object> map = new HashMap<>();
			map.put("id", opalUser.getUserId());
			map.put("text", opalUser.getUserName());
			map.put("iconCls","icon-man");//图标
			return map;
		}).collect(Collectors.toList());
		return collect;
	}

	@Override
	public Object selectAllUserLayuiTableService(String userName) {
		OpalUserExample example= new OpalUserExample();
		userName ="%"+userName+"%";
		example.createCriteria().andUserNameLike(userName);
		List<OpalUser> opalUsers = opalUserMapper.selectByExample(example);
		//layui的table需要code：: 0和msg，数据为data封装
		Map<String, Object> map = new HashMap<>();
		map.put("data", opalUsers);
		map.put("code","0");//状态码 正确的成功状态码应为："code"
		map.put("msg","成功");//状态码 正确的成功状态码应为："code"
		return map;
	}

	@Override
	public Object selectConditionUserService(OpalUser opalUser,Integer page,Integer rows) {
		//处理分页
		Integer before=(page-1)*rows;
		List<OpalUser> users = opalUserExtendMapper.selectConditionUserMapper(opalUser, before, rows);
		int count = opalUserExtendMapper.countConditionUserMapper(opalUser);
		DataGridData result= new DataGridData();
		result.setRows(users);
		result.setTotal(count);
		return result;
	}

	private String getRoleNameByRoleIds(long[] roleId){
		StringBuilder sb = new StringBuilder();
		for(Long id:roleId){
			OpalRole opalRole = opalRoleMapper.selectByPrimaryKey(id);
			String roleName = opalRole.getRoleName();
			sb.append(roleName+",");
		}
		return sb.toString().substring(0, (sb.toString().length()) - 1);
	}

	@Override
	@Transactional("mysqlTransactionManager")
	public ReturnMessageData addUserService(OpalUser opalUser, long[] roleIds) {
		ReturnMessageData rmd= null;
		//处理数据
		opalUser=UserUtils.getNewUser(opalUser);//密码
		try {
			//添加用户
			int i = opalUserMapper.insertSelective(opalUser);
			if(i>0) {
				rmd= new ReturnMessageData(200,"添加用户成功");
			}else {
				rmd= new ReturnMessageData(500,"添加用户失败");
			}
		}catch(DuplicateKeyException e){
			String errorMessage=e.getMessage();
			
			if(errorMessage.indexOf("SQLIntegrityConstraintViolationException")>0) {
				rmd= new ReturnMessageData(500,"用户名已注册，请更换用户名！");
			}
		}catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			e.printStackTrace();
			rmd= new ReturnMessageData(500,"添加用户异常");
		}
		
		return rmd;
	}
	
	@Override
	public Object[] findByUserIdRoleService(long userId) {
		List<Long> result= new ArrayList<Long>();
		OpalUserRoleExample example = new OpalUserRoleExample();
		OpalUserRoleExample.Criteria criteria = example.createCriteria();
		criteria.andUserIdEqualTo(userId);
		List<OpalUserRole> selectByExample = opalUserRoleMapper.selectByExample(example);
		for(OpalUserRole o:selectByExample) {
			result.add(o.getRoleId());
		}
		Object[] array = result.toArray();
		
		return  array;
	}

	@Override
	@Transactional("mysqlTransactionManager")
	public ReturnMessageData updateUserService(OpalUser opalUser, long[] roleIds) {

		//处理密码
		if(StringUtils.isBlank(opalUser.getUserPassword())) {
			opalUser.setUserPassword(null);
		}else {
			opalUser=UserUtils.getNewUser(opalUser);
		}
		ReturnMessageData rmd = null;
		try {
			// 修改用户表
			int i = opalUserMapper.updateByPrimaryKeySelective(opalUser);
			rmd = new ReturnMessageData(200, "修改用户成功");
		} catch (DuplicateKeyException e) {
			//TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			String errorMessage = e.getMessage();
			if (errorMessage.indexOf("SQLIntegrityConstraintViolationException") > 0) {
				rmd = new ReturnMessageData(500, "用户名已存在，请更换用户名称");
			}else {
				rmd = new ReturnMessageData(500, "修改失败！系统维护中或联系管理员");
			}
		} catch (Exception e) {
			e.printStackTrace();
			TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
			rmd = new ReturnMessageData(500, "修改失败！系统维护中或联系管理员");
		}
		return rmd;
	}

	@Override
	@Transactional("mysqlTransactionManager")
	public ReturnMessageData deleteUserService(OpalUser[] opalUser) {
		ReturnMessageData rmd = null;
		try {
			for(OpalUser o:opalUser) {
				//先删除用户与角色关联表
				Long userId = o.getUserId();
				OpalUserRoleExample example=new OpalUserRoleExample();
				example.createCriteria().andUserIdEqualTo(userId);
				int i = opalUserRoleMapper.deleteByExample(example);
				if(i>=0) {
					//删除用户
					int restlt = opalUserMapper.deleteByPrimaryKey(userId);
					if(restlt<0) {
						throw new Exception();
					}
				}else {
					throw new Exception();
				}
			}
			rmd = new ReturnMessageData(200, "删除用户成功");
		}catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			rmd = new ReturnMessageData(500, "删除失败，请尝试重新操作或联系管理员");
		}
		return rmd;
	}

	@Override
	public ReturnMessageData selectAllHrorgService() {

		OpalHrorgExample oh=new OpalHrorgExample();
		List<OpalHrorg> opalHrorgs=null;
		try {
			opalHrorgs = opalHrorgMapper.selectByExample(oh);
		}catch (Exception e){
			e.printStackTrace();
			new ReturnMessageData(500,"查询组织失败：请查看数据库是否运行正常！");
		}
		return new ReturnMessageData(200,"成功",opalHrorgs);
	}

	@Override
	public List<OpalHrorg> getUserOrgHrorgService(HttpServletRequest request) {
		OpalUser user=(OpalUser)request.getSession().getAttribute(CommonConst.OPALUSER);
		List<OpalHrorg> opalHrorgs=null;
		//用户admin 查询全部
		if("admin".equals(user.getUserName())){
			ReturnMessageData returnMessageData = selectAllHrorgService();
			opalHrorgs = (List<OpalHrorg>) returnMessageData.getData();
		}else {
			OpalHrorgExample ohe = new OpalHrorgExample();
            String hrorgPkhrorg = user.getHrorgPkhrorg();
            String[] split = hrorgPkhrorg.split(",");
            ohe.createCriteria().andPkhrorgIn(Arrays.asList(split));
			opalHrorgs = opalHrorgMapper.selectByExample(ohe);
		}

		return opalHrorgs;
	}

	@Override
	public ReturnMessageData getPasswordService(String password) {
		try {
			Subject subject = SecurityUtils.getSubject();
			OpalUser opalUser = (OpalUser)subject.getPrincipal();
			String newPassword = UserUtils.getNewPassword(password,opalUser.getUserSalt());
			if (opalUser.getUserPassword().equals(newPassword)) {
				return new ReturnMessageData(200, null, 1);
			}else {
				return new ReturnMessageData(200, null, 0);
			}
		}catch (Exception e){
			e.printStackTrace();
			log.error("用户验证旧密码发生错误");
			return new ReturnMessageData(500,"请重新登录！");
		}
	}

	@Override
	public ReturnMessageData selfModifyPasswordService(String oldPassword, String newPassword, String newPassword2) {
		Subject subject = SecurityUtils.getSubject();
		OpalUser opalUser = (OpalUser)subject.getPrincipal();
		opalUser.setUserPassword(newPassword);
		//返回随机盐和处理后的密码
		opalUser=UserUtils.getNewUser(opalUser);
		opalUser.setUserUpdated(null);
		try {
			int i = opalUserMapper.updateByPrimaryKeySelective(opalUser);

			if (i>0) {
				log.error("用户【" + opalUser.getUserName() + "】成功修改了密码！");
				return new ReturnMessageData(200,"修改密码成功！");
			}

		}catch (Exception e){
			e.printStackTrace();
			log.error("用户【"+opalUser.getUserName()+"】修改密码发生错误！");
			return new ReturnMessageData(500,"系统维护中，请稍后重试！");
		}

		 return new ReturnMessageData(404,"修改密码失败！");
	}

	@Override
	public List<OpalUser> getOpalUserByUserPosition(Integer userPosition) {
		if (userPosition==null)
			log.error("getOpalUserByUserPosition方法中的条件userPosition未有值");
		OpalUserExample opalUserExample = new OpalUserExample();
		//职位：0：普通员工1、项目经理 2、部门经理，3、总经理、4，总裁，5、内销财务，6、外销财务
		opalUserExample.createCriteria().andUserPositionEqualTo(userPosition);
		List<OpalUser> opalUsers = opalUserMapper.selectByExample(opalUserExample);
		return opalUsers;
	}

	@Override
	public List<OpalUser> getOpalUser(String pkOrg,Integer userPosition) {
		if (StringUtils.isBlank(pkOrg))
			log.error("getOpalUser方法中的条件pkOrg未有值");
		if (userPosition==null)
			log.error("getOpalUser方法中的条件userPosition未有值");
		OpalUserExample opalUserExample = new OpalUserExample();
		//职位：0：普通员工1、项目经理 2、部门经理，3、总经理、4，总裁，5、内销财务，6、外销财务
		opalUserExample.createCriteria().andUserPositionEqualTo(userPosition).andPkOrgEqualTo(pkOrg);
		List<OpalUser> opalUsers = opalUserMapper.selectByExample(opalUserExample);
		return opalUsers;
	}

	@Override
	public List<OpalUser> getBuMenJingLiOpalUser(String userDept){
		//获取当前用户最顶级的部门设置的就是部门经理的部门
		OpalDept opalDept = getOpalDept(userDept);
		//根据部门、职位、来找部门经理
		List<OpalUser> opalUser = getOpalUser(2, opalDept.getPkDept());
		return opalUser;
	}

	private OpalDept getOpalDept(String userDept){
		OpalDeptExample opalDeptExample = new OpalDeptExample();
		opalDeptExample.createCriteria().andPkDeptEqualTo(userDept);//部门1002O110000000000MLW
		List<OpalDept> opalDepts = opalDeptMapper.selectByExample(opalDeptExample);
		OpalDept opalDept = opalDepts.get(0);
		//部门一般都没有父级了，没有父级的~来代替的
		if (!opalDept.getPkFatherorg().equals("~")){
			//递归
			opalDept= getOpalDept(opalDept.getPkFatherorg());

		}
		return opalDept;

	}
	@Override
	public List<OpalUser> getOpalUser(Integer userPosition,String userDept){
			if (StringUtils.isBlank(userDept)) {
				userDept="随便赋值个值吧，不然报错";
				log.error("getOpalUserByUserPosition方法中的条件userDept未有值");
			}
			if (userPosition ==null) {
				userPosition=-1;
				log.error("职位未设置值，给其赋值默认值为-1");
			}
			OpalUserExample opalUserExample = new OpalUserExample();
			//职位：0：普通员工1、项目经理 2、部门经理，3、总经理、4，总裁，5、内销财务，6、外销财务
			opalUserExample.createCriteria().andUserPositionEqualTo(userPosition).andUserDeptEqualTo(userDept);
			List<OpalUser> opalUsers = opalUserMapper.selectByExample(opalUserExample);
			return opalUsers;
	}

	@Override
	public List<OpalUser> getOpalUser(String pkOrg,String userDept,Integer userPosition) {
		if (StringUtils.isBlank(pkOrg)) {
			pkOrg="随便赋值个值吧，不然报错，又不能不赋值，不然查全部";
			log.error("getOpalUserByUserPosition方法中的条件pkOrg未有值");
		}
		if (StringUtils.isBlank(userDept)) {
			userDept="随便赋值个值吧，不然报错";
			log.error("getOpalUserByUserPosition方法中的条件userDept未有值");
		}
		if (userPosition ==null) {
			userPosition=-1;
			log.error("职位未设置值，给其赋值默认值为-1");
		}
		OpalUserExample opalUserExample = new OpalUserExample();
		//职位：0：普通员工1、项目经理 2、部门经理，3、总经理、4，总裁，5、内销财务，6、外销财务
		opalUserExample.createCriteria().andUserPositionEqualTo(userPosition).andPkOrgEqualTo(pkOrg).andUserDeptEqualTo(userDept);
		List<OpalUser> opalUsers = opalUserMapper.selectByExample(opalUserExample);
		return opalUsers;
	}

	@Override
	public List<OpalUser> getOpalUserByUserPosition(String pkOrg,String userDept){
		if (StringUtils.isBlank(pkOrg)) {
			pkOrg="随便赋值个值吧，不然报错，又不能不赋值，不然查全部";
			log.error("getOpalUserByUserPosition方法中的条件pkOrg未有值");
		}
		if (StringUtils.isBlank(userDept)) {
			userDept="随便赋值个值吧，不然报错";
			log.error("getOpalUserByUserPosition方法中的条件userDept未有值");
		}
		OpalUserExample opalUserExample = new OpalUserExample();
		//职位：0：普通员工1、项目经理 2、部门经理，3、总经理、4，总裁，5、内销财务，6、外销财务
			opalUserExample.createCriteria()
					.andPkOrgEqualTo(pkOrg)				//个人组织
					.andUserDeptEqualTo(userDept);

		List<OpalUser> opalUsers = opalUserMapper.selectByExample(opalUserExample);
		return opalUsers;
	}

	@Override
	@Transactional("mysqlTransactionManager")
	public Object updateByUserIdRoleService(Map<String,Object> map) {
		try {
            Integer userId = (Integer) map.get("userId");
			List<Integer> lists= (List<Integer>) map.get("roleIds");
			//先清除用户id中所有的角色
			OpalUserRoleExample example=new OpalUserRoleExample();
			example.createCriteria().andUserIdEqualTo((long)userId);
			opalUserRoleMapper.deleteByExample(example);
			//插入角色id
			for (Integer roleId:lists){
				OpalUserRole opalUserRole = new OpalUserRole();
				opalUserRole.setUserId((long)userId);
				opalUserRole.setRoleId((long)roleId);
				opalUserRoleMapper.insertSelective(opalUserRole);
			}
			opalUserRole=null;
			return new ReturnMessageData(WSC.RESTPONSE_OK,"更新角色成功");
		}catch (Exception e){
			e.printStackTrace();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return new ReturnMessageData(WSC.REQUEST_ERROR,"更新角色失败");
		}
	}

}
